结对编程踩坑指南
背景最近,我开始重新审视这些融入日常的工程实践方式,去尝试找出实际与理论的差距,分析差距成因,基于分析结果,尝试找出可以逐步弥补差距的实践方式,从而让日常软件交付工作变得更加“顺滑”。
本文作为“沉思录”的第一篇,将列举实际交付项目中,在结对编程时遇到的几个实际问题,并针对具体问题给出一些尝试过的解决方式。
如有其他更好的建议,欢迎共同讨论👋。
注意:以下话题不在本文的讨论范围中,并且默认读者已经具备下列问题相关的知识:
为什么进行结对编程?(如果想了解,可以参见维基百科(https://en.wikipedia.org/wiki/Pair_programming) 或其他相关邮件)
怎样开始结对编程?(如果想了解,可以参见《7个你需要知道的结对礼仪》(https://insights.thoughtworks.cn/seven-skills-about-pair-programming/))
9 人团队(1 BA, 1 QA, 1 TL, 6 Devs)
特殊角色(BA,QA, TL)基本都是 Solo 工作,Dev Pair 工作
每对 Pair 同一时间只会工作在一个 User Story 上,直到该 User Story 进入测试阶段
团队在 Sprint 开始时进行 Switch Pair 活动,User Story 未完成的 Pair,会有一人留在未完成的 Story 上,以便完成保证卡片上下文充足
Switch Pair 会按照 Pair 轮换表(如下)进行,以确保所有开发都会有均等的 Pair 机会
Dev轮换表大概是这个样子(每个周期内团队采用同一编号的配对组合):
基于以上的上下文,我们遇到了以下实际问题:
Switch Pair 时,需要交接的内容过多时,可能会漏掉一些细节信息。为了补充遗漏,会陷入更多、更深的讨论。
具体场景
张三和薛霸经过了一周的结对编程,手头的一张复杂 User Story (无法进一步拆分)没有完成,薛霸被留在了当前工作上,准备和阿乐开始工作。
可是,在薛霸向阿乐介绍当前的工作进度时,无法清楚地给阿乐说明之前所写代码与 User Stroy 的对应关系和一些必要的上下文。
于是这对 Pair 不得不将张三重新拉回来,进行上下文交接,三人讨论时间较长,并且会将之前已经讨论过的问题重新讨论,降低了工作效率。
分析原因
后来,张三,薛霸,阿乐对这次效率不尽人意的 Switch Pair 进行了回顾,尝试利用问答的形式进行分析:
对于阿乐的问题,薛霸无法清楚地解答,但在拉回张三后,增加了一些额外的讨论时间,就可以解答了。
问: 结对的两人在当前工作中,理论上应该能够具备相当信息积累。那么,为什么当前薛霸和张三出现了信息积累差异的情况?
答:卡片从 Kick-Off 到当前交接 Switch Pair 的时间跨度较长(7天,含周末),包含内容较多,需要一些讨论重新回想起当时的信息。
另外,薛霸无法解答的问题,基本都是张三在薛霸请假期间完成的。
结对编程理应是有任务拆分(Tasking)作为前提的,以确保 Pair 两人对于当前的工作进度一致,以尽量减轻请假所带来的信息不对称问题。
问:为什么当前的效果并不理想?
答:最初拆分的任务粒度较大,但实际上,在一个大粒度的任务中,会包含一些较小粒度的任务,并且这些任务的完成结果,还会影响后续的任务内容。在工作时,完成了这些较小粒度的任务后,没有将关键工作内容更新到两人共享的任务列表中,于是造成了信息不对称情况。
可尝试的实践
于是,大家总结出了如下可以实行的行动:
初始任务拆分尽量将可能会产生任务分支的关键任务(或问题)标出。
在完成任务的过程中,保持最初任务列表的更新,特别是上述的关键任务,按需记录任务的产出或关键信息。
Switch Pair 围绕任务列表进行,以避免出现内容遗漏或花费额外时间讨论上下文外的问题。
采用Navigator-Driver Pair 模式时,掌握键盘和鼠标的一人(Driver),有时会成兼任 Navigator 角色。
Pair 过程中,一人会处于高度集中状态,另外一人可能会因为没跟上,而从 Pair 中脱出,产生信息断层。
Pair 过程中,如果不作 Driver 的角色,可能无法完全掌握当前 User Story 的全貌。
其实上述的问题是有一定的内在逻辑联系的,可以通过下面的具体场景来进行复现。
具体场景
肖兰和阿发在结对编程过程中,肖兰使用自己的笔记本电脑外接显示器,并通过笔记本的键盘和触控板完成操作,阿发则可以通过外接的显示器看到肖兰的操作。
起初,两人会对着外接显示器进行一些讨论。
但在深入调查代码时和一些代码编写时,肖兰开始对着自己的笔记本屏幕进行操作,随着肖兰逐渐地集中精力,讨论和解说停止了。
在连续几次的进入某个类查看细节代码,再切换到另外几个文件中查看配置文件后,肖兰写了几行代码试了试。
如此反复了几次后,阿发已经不清楚肖兰所进行操作的目的了,但他看着肖兰投入的样子,欲言又止,不忍心打断她的操作。
于是阿发又努力了3分钟尝试跟上肖兰的思路,可是猜透一个人的心思何其难也,阿发最终无奈放弃,于是默默转向自己的电脑(手机),去看看邮件(朋友圈),等待肖兰等下有了结果再同步给他。
可是,肖兰在完成的调查整个过程中获得的信息,却不一定都能同步给阿发,阿发也就无法掌握当前工作的全貌了。
至此,Pair 终成 Solo...
分析原因
硬件设施准备不充分。
肖兰掌控了所有的操作,阿发更多的时候都处于一种“被动”状态,结对编程的参与感不高,特别是当肖兰“全情投入”后,阿发的参与感几乎被全部“剥夺”。
说明:在了解 “如何进行结对编程” 的部分有说明过,结对编程的两人在硬件准备上,应该尽量平等,至少两人都有可以各自操作的键盘。
没有分配、交换角色的活动。
结对编程是两个人共同合作的活动,那么两人中每个个体在活动中的体验感就直接影响这项活动的效果。
在上述例子中,肖兰一开始就掌握了"操作权”,到了代码调查阶段时,肖兰又直接“抢夺”了思维的“导向权”,随着自己的想法去调查、尝试。
导致阿发在这次结对编程中的参与度极低,体验感也极差,并最终转向独自工作。
说明:为了保证结对两人的参与度,结对编程存在多种不同的实践方式(Navigator-Driver 模式、乒乓模式、键盘 + 鼠标模式),但无论采用哪种方式,两人都应在实践一段时间后,交换角色,从而使每人都有机会从不同的视角分析、解决问题。
缺少有效沟通。
结对编程与其说是编程方式,不如说更多是一种“社交”活动。那么,在整个过程中,结对两人需要进行大量,高强度的沟通交流。
在上述场景中,一方面,当肖兰要开始进行一些深入调查时,没有说明意图,从而使阿发开始产生迷茫。
另一方面,当阿发努力尝试后,依然认为自己跟不上肖兰的操作时,没有与肖兰说明情况,从而使两人的“信息鸿沟”进一步被扩大。
可尝试的实践
针对上述问题,可以:
每对Pair中,至少有一人使用从公司申请(自备)的键盘和鼠标,确保每个人都有条件能在想要操作的时候进行操作。
每对Pair按照拆分的任务列表,每完成 1(X)个任务,交换一次两人的角色。
练习提问。结对的两人中,任何一人发现两人的思路不一致时,通过提问的方式,将问题暴露,并解决。
Pair 过程会产生大量的沟通交流,频繁的 Switch Pair 会使这种交流的成本扩大,那么如何从这种高频的 Switch Pair 活动中获得更高的个人收益呢?
具体场景
团队最近在尝试提高 Switch Pair 的频率,从之前的每两周提升到现在的每周一次,之后视情况仍有提升的可能。
而这给阿花造成了困扰,因为几乎每次结对编程,阿花都和搭档会讨论很多问题,而几乎每次 Switch Pair,阿花都需要花费不少时间将这些讨论的结果和新的搭档解释。
阿花认为这降低了工作的效率,并且自己也没从中获得额外的收益,那为什么还要提升 Switch Pair 的频率呢?
分析原因
其实,阿花遇到的工作效率降低问题,可以利用问题1中提到的实践进行尝试。
另外,随着频率的提升,需要传输的信息量也会下降,再加上合理的拆卡,工作效率问题的影响应该微乎其微。
可是,阿花提出的另一个问题,“如何从高频 Switch Pair 中获得更高的个人收益问题?” 这却不是一个单靠结对编程技能就能解答的问题。
先抛开 Switch Pair 的初始目标(信息流动)不谈,因为这其实是对于团队的收益(一定程度上降低团队人员变化带来的风险)。
那么,对个人而言,要想从 Switch Pair 中受益,就需要从敏捷软件工程实践的相关理论和目的出发,如果能结合“快速反馈,识别变化”,那得出👇的结论就不难了:
更频繁的搭档交换,能使反馈的信息源变化,从而使反馈的角度变化,有利于个人从不同视角识别自身的长处与短板。无论是主动通过观察学习,还是通过收集反馈,都提供了更加丰富的输入。
缩短单一搭档工作的时间,但保证周期性的轮换,提供了一个适当的时期(大约一个月)去尝试、应用一些变化,从而在下次轮换到相同的搭档时,可以收集验证性的反馈。
可尝试的实践
想要在高频 Switch Pair 的实践中最大化个人利益,那么就需要充分利用此时的机会和资源,即不同的搭档的视角,再结合 Feedback 机制,就可以很容易构建个人有目的,有针对性的提升计划。
那么就从每次 Switch Pair 前,向上一个搭档收集这段时间合作的反馈开始吧。
注意:Switch Pair 的频率不必一味求高,只要能够确保工作所需的关键信息在团队内充分流动即可。
结对编程也只是程序员工作中会用到的一项技能而已,那么只要是技能,通过时间的堆积,去磨炼,去思考,就会有所提升。
稳扎稳打,时间会给予最棒的回馈!
德雷福斯技能模型 (https://zh.m.wikipedia.org/zh-hk/%E5%BE%B7%E9%9B%B7%E7%A6%8F%E6%96%AF%E6%A8%A1%E5%9E%8B) 结对编程 (https://en.wikipedia.org/wiki/Pair_programming) 结对编程的正确姿势,你会了吗?(https://insights.thoughtworks.cn/pair-programming/) 7个你需要知道的结对礼仪 (https://insights.thoughtworks.cn/seven-skills-about-pair-programming/)
- 相关阅读 -敏捷是知与行的功夫团队的Code Review实践